package org.dromara.generator;


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.converts.DmTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.LikeTable;
import com.baomidou.mybatisplus.generator.config.querys.DMQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import org.dromara.generator.model.GenerModel;
import org.dromara.generator.utils.GenUtils;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.mybatis.core.mapper.MyBaseMapperPlus;

import java.util.HashMap;


/**
 * 代码生成器
 */
public class CodeGenerator {

    /*接口模块路径，生成的entity文件 存放到这里*/
    static String MODULE_API_PATH = "xp-api/xp-api-system/";

    // 生成代码入口main方法
    public static void main(String[] args) {

        GenerModel generModel = GenUtils.getGenerByProps();

        // 1.数据库配置 达梦数据库
        DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig.Builder(generModel.getDbUrl(), generModel.getUsername(), generModel.getPassword())
            .dbQuery(new DMQuery()).typeConvert(new DmTypeConvert())
            .schema(generModel.getDbSchema()) // 达梦数据库需要指定schema,当不同模式存在相同表时，生成代码字段存在问题
            .keyWordsHandler(new MySqlKeyWordsHandler());

        // 1.数据库配置 mysql数据库
//        DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig.Builder(generModel.getDbUrl(), generModel.getUsername(),
//            generModel.getPassword()).dbQuery(new MySqlQuery()).typeConvert(new MySqlTypeConvert())
//            .keyWordsHandler(new MySqlKeyWordsHandler());

        // 1.1.快速生成器
        FastAutoGenerator fastAutoGenerator = FastAutoGenerator.create(dataSourceConfigBuilder);

        // 2.全局配置
        // 覆盖已生成文件
        // 不打开生成文件目录
        // 指定输出目录,注意使用反斜杠\
        // 设置注释的作者
        // 设置注释的日期格式
        // 使用java8新的时间类型
        fastAutoGenerator.globalConfig(globalConfigBuilder -> globalConfigBuilder
//            .enableSwagger()
//                .disableOpenDir()
            .outputDir(MODULE_API_PATH + "\\src\\main\\java").
            author("xpheng").commentDate("yyyy-MM-dd")
            .dateType(DateType.TIME_PACK));

        // 3.包配置
        // 设置父包名
        // 设置父包模块名
        // 设置MVC下各个模块的包名
        // 设置XML资源文件的目录
        fastAutoGenerator.packageConfig(packageConfigBuilder -> packageConfigBuilder.parent(generModel.getParentPackage())
            .moduleName(generModel.getModules())
            .entity("entity")
            .mapper("mappers.mapper")
            .pathInfo(
                new HashMap<OutputFile, String>() {{
                    // mapper.xml文件的保存路径
                    put(OutputFile.xml, MODULE_API_PATH + "\\src\\main\\resources\\mappers\\mapper");
                }})

        );

        // 4.模板配置
        // 使用Freemarker引擎模板，默认的是Velocity引擎模板
        AbstractTemplateEngine templateEngine = new FreemarkerTemplateEngine();
        fastAutoGenerator.templateEngine(templateEngine);

        // 5.注入配置 TODO

        // 6.策略配置
        String[] tableNames = generModel.getTableName().split(",");
        //当表名中带*号时可以启用通配符模式
        if (tableNames.length == 1 && tableNames[0].contains("*")) {
            String[] likeStr = tableNames[0].split("_");
            String likePrefix = likeStr[0] + "_";
            fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.enableCapitalMode().enableSkipView().disableSqlFilter()
                // 设置需要生成的表名
                .likeTable(new LikeTable(likePrefix)));
        } else {
            fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.enableCapitalMode().enableSkipView().disableSqlFilter()
                // 设置需要生成的表名
                .addInclude(tableNames)

            );
        }


        // 6.1.Entity策略配置
        // 生成实体时生成字段的注解，包括@TableId注解等
        // 数据库表和字段映射到实体的命名策略，为下划线转驼峰
        // 全局主键类型为None
        // 实体名称格式化为XXXEntity
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.entityBuilder().enableTableFieldAnnotation() // 生成实体时生成字段的注解，包括@TableId注解等
                .enableFileOverride() // 开启文件覆盖
                .enableLombok()  // 开启lombok支持
                .naming(NamingStrategy.underline_to_camel) // 数据库表和字段映射到实体的命名策略，为下划线转驼峰
                .columnNaming(NamingStrategy.underline_to_camel).idType(IdType.NONE) // 全局主键类型为None

                // 设置Entity父类
                .superClass(BaseEntity.class)
                // BaseEntity类的公共字段
                .addSuperEntityColumns("CREATED_BY", "CREATE_TIME", "UPDATE_BY", "UPDATE_TIME")
//                .formatFileName("%sEntity")
        );

        // 6.2.Controller策略配置
        // 开启生成@RestController控制器
//        fastAutoGenerator
//            .strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.controllerBuilder().enableRestStyle()
//                .disable() //禁用service生成
//            );

        // 6.3.Service策略配置
        // 格式化service接口和实现类的文件名称，去掉默认的ServiceName前面的I
//        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.serviceBuilder().formatServiceFileName("I%sService")
//            .formatServiceImplFileName("%sServiceImpl")
//            .disable() // 禁用service生成
//        );

        // 6.4.Mapper策略配置
        // 格式化 mapper文件名,格式化xml实现类文件名称
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.mapperBuilder().enableBaseResultMap().enableBaseColumnList()
            .enableFileOverride() // 开启文件覆盖
            .formatMapperFileName("%sMapper").formatXmlFileName("%sMapper")
            .superClass(MyBaseMapperPlus.class));


        // 不生成servce、serviceImpl和controlller
        fastAutoGenerator.templateConfig(templateConfig -> templateConfig.service("").disable());
        fastAutoGenerator.templateConfig(templateConfig -> templateConfig.serviceImpl("").disable());
        fastAutoGenerator.templateConfig(templateConfig -> templateConfig.controller("").disable());


        // 7.生成代码
        fastAutoGenerator.execute();


    }
}

